package cn.tuling.v2;

/**
 * v1版本可以完成基本操作，但很不严谨，因为四种状态运行时都需要具备"前提"
 * <p>
 * 缺陷：
 * 1. 电梯实现类Lift很长，不利于维护。太多if-else分支，在业务复杂的情况下，程序会更长。
 * 2. 扩展性差，违反 “开闭原则”。 如果再有其他状态，每个方法都要增加N种状态的switch-case
 */
public class StateTest {
    public static void main(String[] args) {
        ILift lift = new Lift();
        lift.setState(ILift.STOPPING);
        lift.open();
        lift.close();
        lift.run();
        lift.stop();
    }
}

interface ILift {
    int OPENING = 1;
    int CLOSING = 2;
    int RUNNING = 3;
    int STOPPING = 4;

    void setState(int state);

    // 开门
    void open();

    // 关门
    void close();

    // 运行
    void run();

    // 停止
    void stop();
}

class Lift implements ILift {
    private int state;

    @Override
    public void setState(int state) {
        this.state = state;
    }

    @Override
    public void open() {
        switch (state) {
            case OPENING:
            case RUNNING:
                break;
            case CLOSING:
            case STOPPING:
                this.openWithoutLogic();
                this.setState(OPENING);
                break;
        }
    }

    @Override
    public void close() {
        switch (state) {
            case OPENING:
                this.closeWithoutLogic();
                this.setState(CLOSING);
                break;
            case CLOSING:
            case RUNNING:
            case STOPPING:
                break;
        }
    }

    @Override
    public void run() {
        switch (state) {
            case OPENING:
            case RUNNING:
                break;
            case CLOSING:
            case STOPPING:
                this.runWithoutLogic();
                this.setState(RUNNING);
                break;
        }
    }

    @Override
    public void stop() {
        switch (state) {
            case OPENING:
            case STOPPING:
                break;
            case CLOSING:
            case RUNNING:
                this.stopWithoutLogic();
                this.setState(STOPPING);
                break;
        }
    }

    // 纯粹的开门、关门、运行、停止，不考虑逻辑
    public void openWithoutLogic() {
        System.out.println("电梯开门");
    }

    public void closeWithoutLogic() {
        System.out.println("电梯关门");
    }

    public void runWithoutLogic() {
        System.out.println("电梯运行");
    }

    public void stopWithoutLogic() {
        System.out.println("电梯停止");
    }
}